package p33_HandlerMapper和HandlerAdapter其1;

import org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping;
import org.springframework.web.servlet.mvc.Controller;
import org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * 前面介绍了RequestMappingHandlerMapping和RequestMappingHandlerAdapter，一个做路径映射，一个根据映射调用控制器方法
 * 其实映射器和适配器的顶层接口分别是：HandlerMapping，HandlerAdapter
 * RequestMappingHandlerMapping和RequestMappingHandlerAdapter只是这两个接口的其中一个实现类而已
 * 还有很多其他实现类，比如这章介绍的:BeanNameUrlHandlerMapping和SimpleControllerHandlerAdapter，根据bean名称来做映射
 */
@Configuration
public class _1_BeanNameUrlHandlerMapping和SimpleControllerHandlerAdapter {
    public static void main(String[] args) {
        /**
         * WebConfig配置文件中注入的HandlerMapping和HandlerAdapter，就是BeanNameUrlHandlerMapping和SimpleControllerHandlerAdapter
         * DispatcherServlet就会使用这两个实现类
         */
        AnnotationConfigServletWebServerApplicationContext context =
                new AnnotationConfigServletWebServerApplicationContext(WebConfig.class);
    }

    /**
     * 处理器映射器和处理器适配器，除了前面介绍的两个，还有其他实现
     * BeanNameUrlHandlerMapping和SimpleControllerHandlerAdapter就是一对实现
     *  1.BeanNameUrlHandlerMapping:也是做路径映射，只是不找RequestMapping注解作为映射的url，而是用bean的名字作为路径映射(以/开头的bean)
     *  2.SimpleControllerHandlerAdapter:与BeanNameUrlHandlerMapping配合的适配器
     */
    @Bean
    public BeanNameUrlHandlerMapping beanNameUrlHandlerMapping() {
        return new BeanNameUrlHandlerMapping();
    }
    @Bean
    public SimpleControllerHandlerAdapter simpleControllerHandlerAdapter() {
        return new SimpleControllerHandlerAdapter();
    }

    /**
     * 定义几个控制器(bean名称以/开头，这种一个lei只有一个控制器方法)
     */
    @Component("c1")
    static class Controller1 implements Controller {
        //这个bean的名称没有/开头
        @Override
        public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {
            response.getWriter().printf("this is c1");
            return null;
        }
    }
    @Component("/c2")
    static class Controller2 implements Controller {
        //这个bean的名称以/开头
        @Override
        public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {
            response.getWriter().printf("this is c2");
            return null;
        }
    }
    @Component("/c3")
    static class Controller3 implements Controller {
        //这个bean的名称以/开头
        @Override
        public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {
            response.getWriter().printf("this is c3");
            return null;
        }
    }
}
